\begin{lstlisting}[frame=shadowbox, language=C, breaklines=true, basicstyle=\footnotesize]

#include <mips/regdef.h>
#include <sys/syscall.h>

#define STD_IN           0
#define STD_OUT          1
#define STD_ERROR        2

#define CANT_REALLOC   100

#define TAM_FRAME       48

#define POS_SRA_RA      40
#define POS_SRA_FP      36
#define POS_SRA_GP      32

#define LA_TAM_BUFF     28
#define LA_CONTADOR     24
#define LA_BUFF         20
#define LA_BUFF_OLD     16

   .data 
msj_error: .asciiz ``Error en la asignacion de memoria\''

   .text
   .align 2
   .globl main
   .ent main

main:
   .frame        $fp ,TAM_FRAME, ra
   .set noreorder
   .cpload t9
   .set reorder
   subu          sp,sp, TAM_FRAME
   .cprestore POS_SRA_GP
   sw            $fp, POS_SRA_FP (sp)
   sw            ra, POS_SRA_RA (sp)

   move          $fp,sp

   move          a0, zero
   li            a1, CANT_REALLOC
   la            t9, realocar
   jal           t9 #asigno el tamano del buffer por primera vez

#chequeo
   move          t7, v0
   sw            v0, LA_BUFF_OLD (sp) #guardamos direccion al puntero al buffer
   addu          t4, zero, CANT_REALLOC #tamano buffer
   addu          t3, zero, zero

#LA 
#0 - DIR del buffer
#4 - Puntero a la ultima pos del buffer alamcenada
#8 - contador
#12 - tamano del buffer (memoria allocada)

while:

   sw            t7, LA_BUFF(sp) # guarda buffer antes de la llamada a read.
   sw            t3, LA_CONTADOR(sp) # guarda contador antes de la llamada a read.
   sw            t4, LA_TAM_BUFF(sp) # guarda tamano del buffer

   bne           t3, t4, jump #salteo el realocar ( no la estamos guardando arriba)      
   lw            a0, LA_BUFF_OLD(sp)
   mul           a1, t4, 2 #el nuevo tamano del buffer es 2*tamano viejo
   sw            a1, LA+12(sp) # guarda tamano del buffer
   la            t9, realocar
   jal           t9

      lw         t3, LA_CONTADOR(sp)
      sw         v0, LA_BUFF_OLD(sp) # guardo el nuevo buffer ya que realocar puede moverlo de posicion. 
      addu       t7, t3, v0 # volver a poner la posicion del buffer en el nuevo bloque.
      sw         t7, LA_BUFF (sp) # guarda buffer antes de la llamada a read.
     
   jump:

      #preparo llamada al read
      li         a0, STD_IN #file Descriptor STDIN
      move       a1, t7  #Puntero al buffer
      li         a2, 1  #tamano a leer
      la         t9, read
      jal        t9

      lw         t7, LA_BUFF(sp) #lo carga otra vez.
      lw         t3, LA_CONTADOR(sp) #lo carga otra vez.
      lw         t4, LA_TAM_BUFF(sp) #lo carga otra vez.

      addu       t3, t3, 1 # aumento el contador.
      addu       t7, t7, 1 #muevo el puntero al buffer la cant de posiciones q lei.
      bne        v0, 1, eof #comparo el ultimo caracter leido a ver si es fin de archivo.
b while


error:
   li            a0, STD_OUT 
   la            a1, msj_error 
   li            a2, 3
   la            t9, write
   jal           t9
   li            v0, SYS_exit
   syscall

eof:
   lw            a0, LA_BUFF_OLD(sp)
   lw            a1, LA_CONTADOR(sp)
   la            t9, imprimir
   jal           t9
   lw            a0, LA_BUFF_OLD(sp) #recupera la posicion del buffer para liberarlo.
   la            t9, desalocar
   jal           t9
   move          v0, zero
   move          sp, $fp
   lw            ra, POS_SRA_RA(sp)#recupero ra
   lw            $fp, POS_SRA_FP(sp)
   addu          sp, sp,TAM_FRAME
   j             ra # vuelvo al sistema operativo.

.end main
\end{lstlisting}
